# 新邮件检测与命令执行
import time
import threading
from abc import abstractmethod, ABCMeta

from py.storage import AppObj
from py.storage.SettingUtil import setting, mail
from py.uitls import EmailUtil
from py.uitls.Logger import myLogger


class EmailServer(metaclass=ABCMeta):

    def __init__(self):
        # 任务状态，用于终止任务
        self.__running = True

    def start(self):
        self.__running = True
        threading.Thread(target=self.__run).start()

    def terminate(self):
        self.__running = False
        print("终止任务执行")

    @abstractmethod
    def handle_mail_by_pop(self, pop_server):
        pass

    @abstractmethod
    def server_connecting(self):
        pass

    @abstractmethod
    def server_login_success(self, pop_server):
        pass

    @abstractmethod
    def server_connect_fail(self):
        pass

    @abstractmethod
    def server_unknown_error(self):
        pass

    @abstractmethod
    def server_login_fail(self):
        pass

    def __run(self):
        # 是否重新连接，某些情况下，服务被关闭了
        is_reconnecting = True

        while self.__running:
            time.sleep(2)
            time.sleep(float(setting.sleep))

            # 手动停止了服务
            if not AppObj.service:
                # 停止额服务则是重连，是否属于重连
                is_reconnecting = True
                continue

            if AppObj.service:
                try:
                    if is_reconnecting:
                        self.server_connecting()

                    try:
                        pop_connect = EmailUtil.get_pop_connect(mail.pop_server, mail.pop_port)
                    except Exception as result:
                        myLogger.info(result)
                        self.server_connect_fail()
                        continue

                    try:
                        pop_server = EmailUtil.get_pop_login(pop_connect, mail.user, mail.pwd)
                        if is_reconnecting:
                            self.server_login_success(pop_server)

                        self.handle_mail_by_pop(pop_server)

                    except Exception as result:
                        myLogger.info(result)
                        self.server_login_fail()
                        continue

                    is_reconnecting = False

                except Exception as result:
                    myLogger.info(result)
                    self.server_unknown_error()
